﻿using AntdUI;
using AttendanceSysytem.Database.BusinessLogic;
using AttendanceSysytem.Models;
using MathNet.Numerics;
using Microsoft.IdentityModel.Tokens;
using MiniExcelLibs;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Bcpg.Sig;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utilities.IO.EXCEL;
using static NPOI.HSSF.Util.HSSFColor;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;

namespace AttendanceSysytem.Controls
{
    public partial class AttendancePage : UserControl
    {
        WorkScheduling_Logic logic = new WorkScheduling_Logic();
        Employee_Logic emp_Logic = new Employee_Logic();
        Config_Logic config_Logic = new Config_Logic();
        public AttendancePage()
        {
            InitializeComponent();

            if (Debugger.IsAttached)
            {
                txtFile1.Text = @"C:\Users\pc-admin\Desktop\考勤测试数据\1月\上下班打卡_日报_20250101-20250123.xlsx";
                txtFile2.Text = @"C:\Users\pc-admin\Desktop\考勤测试数据\1月\外出打卡_日报_20250101-20250123.xlsx";
                txtTemplateFile.Text = @"C:\Users\pc-admin\Desktop\考勤测试数据\1月\2025年1月考勤记录汇总表.xlsx";
                txtProdFile.Text = @"C:\Users\pc-admin\Desktop\考勤测试数据\1月\prod.xlsx";

            }

        }


        public void MessageBoxShow(string message, TType type = TType.Info)
        {
            AntdUI.Modal.open(new AntdUI.Modal.Config(this.FindForm(), "消息", message)
            {
                Icon = type,
                //内边距
                Padding = new Size(24, 20),
                OkText = "Confirm",
                CancelText = null,
            });
        }


        private void btnSave_Click(object sender, EventArgs e)
        {
            AntdUI.Spin.open(panel1, new AntdUI.Spin.Config()
            {
                Back = Color.FromArgb(220, 147, 181, 207),
                Color = Style.Db.Primary,//转圈颜色

                Radius = 6,
                Fore = Color.Black,//字体颜色
                Font = new Font("Microsoft YaHei UI", 14f),//字体可以控制进度圈的大小
            }, (config) =>
            {
                config.Value = 0.2f;
                //耗时代码，处理数据
                config.Text = "正在处理中...";
                ProccessFile();
                config.Value = 1.0f;
                config.Text = "处理完成!";
                Thread.Sleep(500);
            }, () =>
            {
                //结束时执行的代码
            });


        }

        private void ProccessFile()
        {

            string file1 = txtFile1.Text;
            string file2 = txtFile2.Text;
            string templateFile = txtTemplateFile.Text;
            string prodFile = txtProdFile.Text;
            if (!File.Exists(file1))
            {
                MessageBoxShow("请选择总部考勤Excel文件", TType.Error);
                return;
            }
            if (!File.Exists(file2))
            {
                MessageBoxShow("请选择外出考勤Excel文件", TType.Error);
                return;
            }

            if (File.Exists(prodFile))
            {
                //MessageBoxShow("生成结果文件已经存在，请先删除", TType.Error);
                //return;
            }

            try
            {
                //总部打卡数据
                var rows1 = MiniExcel.Query<Import_WorkAttendanceRecords>(file1, startCell: "A4");

                //总部打卡详情数据
                var rowsDetail = MiniExcel.Query<Import_WorkAttendanceDetailRecords>(file1, sheetName: "打卡详情", startCell: "A4");

                //外部打卡数据
                var rows2 = MiniExcel.Query<Import_OuterWorkAttendanceRecords>(file2, startCell: "A3");

                //请假数据
                var leaveRecords = MiniExcel.Query<ImportLeaveRecord>(templateFile, sheetName: "请假单").Where(a => a.Account != null).ToList();

                //生成员工打卡数据
                var ClockinDatas = BuildEmployeeClockinData(rows1, rows2, rowsDetail);

                //填充模版数据
                NpoiHelper excelNpoi = new NpoiHelper(templateFile, 1);
                excelNpoi.ChangeSheet("考勤表-明细");
                /*
                 * 从第6行第2列读取部门
                 * 从第6行第3列读取姓名
                 * 
                 * 写入从第6行第5列开始
                 * 
                 */

                var sheet = excelNpoi.Sheet;
                int startrow = 6 - 1;
                int startcol = 2 - 1;

                //得到模板中的天数信息
                var date = sheet.GetRow(startrow - 1).GetCell(4).DateCellValue;
                var maxday = date.Value.AddMonths(1).AddDays(-1).Day;

                LastPosition lastPos = excelNpoi.GetLastPosition();

                //更新考勤明细
                while (true)
                {

                    int col = startcol; //列复位

                    if (lastPos.lastRow <= startrow)
                        break; // 超出最大行数
                    var row = sheet.GetRow(startrow);
                    var departCell = row.GetCell(col++);
                    if (departCell == null) //虽然没有结尾但是已经达到模板的最后数据
                        break;
                    string depart = departCell.StringCellValue;
                    string name = row.GetCell(col++).StringCellValue;
                    if (name.IsNullOrEmpty())
                        break;

                    if (name == "赵云凤")
                    {

                    }

                    var emp = ClockinDatas.Find(a => a.EmployeeName == name && a.Depart_Text.Contains(depart));

                    //var emp9 = ClockinDatas.Find(a => a.EmployeeName == "赵云凤" && a.Depart_Text.Contains(depart));

                    if (emp != null && emp.EmployeeName == "赵云凤")
                    {
                    }
                    col = UpdateEmployeeAttendanceXlsx(excelNpoi, startrow, maxday, col, emp, leaveRecords);
                    //每个员工信息占6行数据
                    startrow = startrow + 6;
                }

                //更新考勤表
                excelNpoi.ChangeSheet("考勤表"); //考勤表
                sheet = excelNpoi.Sheet;
                lastPos = excelNpoi.GetLastPosition();
                startcol = 1;
                int rowIndex = 2;
                while (true)
                {
                    int col = startcol; //列复位

                    if (lastPos.lastRow <= rowIndex)
                        break; // 超出最大行数
                    var row = sheet.GetRow(rowIndex);
                    var departCell = row.GetCell(col++);
                    if (departCell == null) //虽然没有结尾但是已经达到模板的最后数据
                        break;
                    string depart = departCell.StringCellValue;
                    string name = row.GetCell(col++).StringCellValue;
                    if (name.IsNullOrEmpty())
                        break;
                    var emp = ClockinDatas.Find(a => a.EmployeeName == name && a.Depart_Text.Contains(depart));

                    if (emp != null)
                    {
                        excelNpoi.SetSheetData(emp.StandardWorkDay.ToString(), rowIndex, col);
                        excelNpoi.SetSheetData(emp.RealWorkDay.ToString(), rowIndex, col + 1);
                        if (emp.ClockRule != "车间")//办公室
                        {
                            excelNpoi.SetSheetData("", rowIndex, 6);
                            excelNpoi.SetSheetData("", rowIndex, 7);
                        }
                        else
                        {
                            excelNpoi.SetSheetData(emp.WorkDayOvertimeHour.ToString(), rowIndex, 6);
                            excelNpoi.SetSheetData(emp.RestDayOvertimeHour.ToString(), rowIndex, 7);
                        }
                        excelNpoi.SetSheetData(emp.TotalFoodTimes.ToString(), rowIndex, 9);
                        excelNpoi.SetSheetData((emp.TotalFoodTimes * 15).ToString(), rowIndex, 10);
                        excelNpoi.SetSheetData(emp.TotalSickLeaveTimes.ToString(), rowIndex, 11);
                        excelNpoi.SetSheetData(emp.TotalBereavementLeaveTimes.ToString(), rowIndex, 12);
                        excelNpoi.SetSheetData(emp.TotalAffairsLeaveTimes.ToString(), rowIndex, 13);
                        excelNpoi.SetSheetData(emp.TotalRestLeaveTimes.ToString(), rowIndex, 14);
                        excelNpoi.SetSheetData(emp.TotalAnnualLeaveTimes.ToString(), rowIndex, 15);
                        if (emp.ClockRule != "车间")//办公室
                        {
                            excelNpoi.SetSheetData((emp.WorkDayOvertimeHour + emp.RestDayOvertimeHour).ToString(), rowIndex, 17);
                        }
                    }
                    rowIndex++;
                }

                if (File.Exists(prodFile))
                    File.Delete(prodFile);
                excelNpoi.SaveWorkbook(prodFile);
                MessageBoxShow("保存完毕");
            }
            catch (Exception ex)
            {
                MessageBoxShow($"异常: {ex.Message}", TType.Error);
            }
        }

        private int UpdateEmployeeAttendanceXlsx(NpoiHelper excelNpoi, int startrow, int maxday, int col, Calc_EmployeeWorkAttendanceRecords emp, List<ImportLeaveRecord> leaveRecords)
        {

            //先提取所有员工数据、排班数据以作备用
            var workSchedulings = logic.AllList();
            var allEmps = emp_Logic.AllList();
            var overTimeConfig = config_Logic.Queryable().Where(a => a.Configkey == "system.overtime.offset").Single();
            var offsetMinutes = overTimeConfig.Value.ObjToInt();
            if (emp != null && emp.AttendanceDetails.Count <= maxday)
            {
                var one = allEmps.Find(a => a.Account == emp.Account);
                if (one == null)
                    return 0;

                var schedulings = workSchedulings.FindAll(a => a.EmployeeType == one.TimeRule);

                var MinDate = emp.AttendanceDetails.Max(a => a.WorkDate);
                int lstDateCol = col + maxday + 1;//当月的最后一列

                for (int i = 1; i <= maxday; i++)
                {
                    var collectIndex = lstDateCol;
                    var rowIndex = startrow;
                    bool todayIsRest = false;//今日是否假日
                    bool TodayIsOK = false; //今日白班是否正常
                    col++; //日期所在列
                    var record = emp.AttendanceDetails.Find(a => a.WorkDate.Day == i);

                    string dateKey = $"{MinDate.ToString("yyyy-MM")}-{i.ToString().PadLeft(2, '0')}";
                    var scheduling = schedulings.Find(a => a.DateKey == dateKey);
                    var CalcDate = dateKey.ObjToDate();

                    if (emp.EmployeeName == "高勇")
                    {

                    }


                    //办公室的是6点起开始算加班、车间的是6:30起开始算加班
                    DateTime DayOFFTime = new DateTime();

                    //默认周-到周五上班 、周六天休息， 
                    if (scheduling == null)
                    {
                        DayOFFTime = CalcDate.ToString("yyyy-MM-dd 18:00:00").ObjToDate();
                        if (CalcDate.DayOfWeek == DayOfWeek.Sunday || CalcDate.DayOfWeek == DayOfWeek.Saturday)
                            todayIsRest = true;
                    }
                    else
                    {
                        if (scheduling.EmployeeType == 1)
                        {
                            DayOFFTime = CalcDate.ToString("yyyy-MM-dd 18:00:00").ObjToDate();
                        }
                        else
                        {
                            DayOFFTime = CalcDate.ToString("yyyy-MM-dd 18:30:00").ObjToDate();
                        }
                        if (scheduling.Status == 2)
                            todayIsRest = true;
                    }
                    if (!todayIsRest)
                    {
                        emp.StandardWorkDay++;
                    }


                    //DateTime DayOFFTime = CalcDate.ToString("yyyy-MM-dd 18:00:00").ObjToDate();


                    string morning = ""; //上午打卡时间
                    string afternoon = ""; //下午打卡时间
                    string overtime = ""; //加班时间

                    string leave = "";   //请假时间
                    int FoodTimes = 0;
                    string FoodSubsidy = ""; //餐补
                    string Outer = ""; // 外出


                    decimal normalHour = 0;
                    if (record != null)
                    {
                        if (record.EarliestTime != null)
                        {
                            morning = record.EarliestTime.Value.ToString("HH:mm");
                        }
                        if (record.LatestTime != null)
                        {
                            afternoon = record.LatestTime.Value.ToString("HH:mm");

                            if (record.LatestTime.Value.Day > i)
                                 afternoon = $"次日{afternoon}";

                            //var ts = record.LatestTime.Value - DayOFFTime;//这里会有问题 即使LatestTime小 相减还是正的时间
                            var ts = new TimeSpan();
                            if (DateTime.Compare(record.LatestTime.Value, DayOFFTime) > 0)//下班时间大于18：00
                            {
                                ts = record.LatestTime.Value - DayOFFTime;
                            }
                            else
                            {
                                ts = new TimeSpan(0, 0, 0);
                            }


                            ts = ts.Add(TimeSpan.FromMinutes(offsetMinutes));//追加偏移量


                            if (ts.TotalMinutes > 0)
                                overtime = ts.Minutes >= 30 ? $"{ts.Hours}.5" : $"{ts.Hours}";


                            overtime = overtime.Equals("0") ? "" : overtime;
                            //if (ts.TotalHours >= 2 && !((!record.CheckInEarliestLocation.IsNullOrEmpty() && !record.CheckInEarliestLocation.Contains("上海市"))
                            //    || (!record.CheckInLatestLocation.IsNullOrEmpty() && !record.CheckInLatestLocation.Contains("上海市"))))

                            if (ts.TotalHours >= 2 && record.WorkType != 2 && record.WorkType != 4 && CheckWorkPlace(record.CheckInEarliestLocation))//上班时间大于2小时，没外出，没休息才能算饭补
                            {
                                FoodTimes++;
                            }
                            if (emp.EmployeeName == "梁薇")
                            {

                            }
                            //计算餐补
                            if (record.EarliestTime != null && record.WorkType != 4)
                            {
                                if (!todayIsRest)
                                {
                                    emp.RealWorkDay++;//算出勤
                                }
                                if (record.LatestTime != record.EarliestTime)//说明漏打下班卡
                                {
                                    if (!todayIsRest)
                                    {
                                        //判断当天是否存在调休
                                        //检查今日是否有请假情况
                                        var leaveRecordData = leaveRecords.Find(a => a.Account.ToLower() == emp.Account.ToLower()
                                                    && a.LeaveHour > 0 && a.DayInfos.ContainsKey(dateKey));
                                        if (!(leaveRecordData != null && Double.Parse(leaveRecordData.DayInfos[dateKey].Hour.ToString()) > 5))
                                        {
                                            //if (!((!record.CheckInEarliestLocation.IsNullOrEmpty() && !record.CheckInEarliestLocation.Contains("上海市"))
                                            //    || (!record.CheckInLatestLocation.IsNullOrEmpty() && !record.CheckInLatestLocation.Contains("上海市"))))
                                            if (CheckWorkPlace(record.CheckInEarliestLocation) && CheckWorkPlace(record.CheckInLatestLocation))
                                            {
                                                FoodTimes++;
                                            }
                                            TodayIsOK = true;
                                        }
                                    }
                                    else
                                    {
                                        ts = record.LatestTime.Value - record.EarliestTime.Value;
                                        if (ts.TotalMinutes > 0)
                                            normalHour = ts.Minutes >= 30 ? Convert.ToDecimal($"{ts.Hours}.5") : Convert.ToDecimal($"{ts.Hours}");
                                        if (DateTime.Compare(record.LatestTime.Value, DayOFFTime) > 0)
                                        {
                                            normalHour = normalHour - overtime.ObjToDecimal();
                                        }
                                        TodayIsOK = true;
                                    }
                                }

                                if (morning == afternoon)
                                {
                                    //检测漏打卡
                                    if (record.EarliestTime < record.EarliestTime.Value.ToString("yyyy-MM-dd 12:00:00").ObjToDate())
                                        afternoon = "漏打卡";
                                    else
                                        morning = "漏打卡";

                                    emp.MissedPunch++;
                                }
                            }

                            //若今日是休息日，需要叠加加班时间
                            if (todayIsRest)
                            {
                                var newovertime = overtime.ObjToDecimal() + normalHour;
                                if (emp.EmployeeName == "李相印")
                                {

                                }
                                //判断双休日工时 双休日工时，如果是上午11:00前来就需要减1个小时； 过了18:00就要减0.5小时
                                if (morning.Contains(":") && afternoon.Contains(":"))
                                {
                                    if (DateTime.Compare(Convert.ToDateTime(morning), "11:00:00".ObjToDate()) < 0)
                                    {
                                        newovertime = newovertime - 1;
                                    }
                                    if (!afternoon.Contains("次日"))
                                    {
                                        if (DateTime.Compare(Convert.ToDateTime(afternoon), "18:00:00".ObjToDate()) > 0)
                                        {
                                            newovertime = newovertime - (decimal)0.5;
                                        }
                                    }
                                    else//包含次日
                                    {
                                        if (DateTime.Compare(Convert.ToDateTime(record.LatestTime), "18:00:00".ObjToDate()) > 0)
                                        {
                                            newovertime = newovertime - (decimal)0.5;
                                        }
                                    }
                                }
                                else //存在漏打卡、未打卡 预留！！！
                                {

                                }

                                emp.RestDayOvertimeHour += newovertime;
                                overtime = $"{newovertime}";
                                //if (newovertime >= 3 && !((!record.CheckInEarliestLocation.IsNullOrEmpty() && !record.CheckInEarliestLocation.Contains("上海市"))
                                //    || (!record.CheckInLatestLocation.IsNullOrEmpty() && !record.CheckInLatestLocation.Contains("上海市"))))//休息日满3小时就要有餐补
                                if (newovertime >= 3 && CheckWorkPlace(record.CheckInEarliestLocation) && CheckWorkPlace(record.CheckInLatestLocation))//休息日满3小时就要有餐补
                                {
                                    FoodTimes++;
                                }
                            }
                            else
                            {
                                emp.WorkDayOvertimeHour += overtime.ObjToDecimal();

                            }

                            FoodSubsidy = FoodTimes.ToString();

                            //if (FoodTimes > 0)
                            //{
                            //只要打卡了就算出勤
                            //emp.RealWorkDay++;
                            //}
                            emp.TotalFoodTimes += FoodTimes;
                        }

                        if (record.EarliestTime == null && record.LatestTime == null && (record.WorkType == 1 || record.WorkType == 2))
                        {
                            afternoon = morning = "未打卡";
                            emp.NoCardPunched++;
                        }


                        //不为空 计算迟到

                        //if (row.CalibrationConditionText.Contains("迟到") || row.CalibrationConditionText.Contains("旷工"))//旷工、迟到都需要看外出打卡
                        //{
                        //    string date = row.Date_Text.Substring(0, row.Date_Text.Length - 3).TrimEnd();
                        //    var ins = row.Where(x => x.EmployeeName == emp.EmployeeName && x.Account == emp.Account && x.Date_Text.Contains(date/*row.Date_Text*/));
                        //    if (ins.Any())
                        //    {
                        //        row.EarliestText = ins.First().EarliestText;
                        //        if (row.EarliestText.ObjToDate() > "8:30".ObjToDate())
                        //        {
                        //            emp.BeLateCount++;
                        //            emp.TotalLateTimes += Convert.ToDouble(Regex.Replace(row.CalibrationConditionText, @"[^0-9]+", ""));
                        //        }
                        //    }
                        //    else//为空 说明连外出打卡记录都没有 就算迟到了
                        //    {
                        //        emp.BeLateCount += row.CalibrationConditionText.Contains("迟到") ? 1 : 0;//包含迟到就加1
                        //        emp.TotalLateTimes += Convert.ToDouble(Regex.Replace(row.CalibrationConditionText.Split('、').First(), @"[^0-9]+", ""));
                        //    }                          
                        //}

                        if (record.CalibrationConditionText.Contains("迟到") || record.CalibrationConditionText.Contains("旷工"))//旷工、迟到都需要看外出打卡
                        {
                            if (record.EarliestTime?.ToString("HH:mm").ObjToDate() > "8:30".ObjToDate())
                            {
                                emp.BeLateCount++;
                                emp.TotalLateTimes += Convert.ToDouble(Regex.Replace(record.CalibrationConditionText, @"[^0-9]+", ""));
                            }
                        }
                    }

                    if (emp.EmployeeName == "梁薇" && i == 14)
                    {

                    }
                    var ss = leaveRecords.FindAll(a => a.Account.ToLower() == emp.Account.ToLower());
                    //检查今日是否有请假情况
                    var leaveRecord = leaveRecords.Find(a => a.Account.ToLower() == emp.Account.ToLower()
                                && a.LeaveHour > 0 && a.DayInfos.ContainsKey(dateKey));

                    if (leaveRecord != null && !todayIsRest)
                    {
                        var leaveInfo = leaveRecord.DayInfos[dateKey];

                        leave = leaveInfo.Hour.ToString();
                        var leaveoption = leaveInfo.DayOption;
                        string leavetext = "病假、调休、事假".Contains(leaveRecord.LeaveTypeText) ? "调休" : leaveRecord.LeaveTypeText;
                        switch (leaveoption)
                        {
                            case DayOption.FullDay:
                                morning = afternoon = leavetext;
                                emp.RealWorkDay++;//全天调休算出勤
                                break;
                            case DayOption.Moring:
                                morning = leavetext;
                                emp.RealWorkDay++;//算出勤
                                break;
                            case DayOption.Afternoon:
                                afternoon = leavetext;
                                emp.RealWorkDay++;//算出勤
                                break;
                            default:
                                break;
                        }
                        switch (leaveRecord.LeaveType)
                        {
                            case LeaveType.Sick:
                                emp.TotalSickLeaveTimes += leaveInfo.Hour;
                                break;
                            case LeaveType.Annual:
                                emp.TotalAnnualLeaveTimes += leaveInfo.Hour;
                                break;
                            case LeaveType.Lieu:
                                emp.TotalRestLeaveTimes += leaveInfo.Hour;
                                break;
                            case LeaveType.Affairs:
                                emp.TotalRestLeaveTimes += leaveInfo.Hour;
                                break;
                            case LeaveType.Bereavement:
                                emp.TotalBereavementLeaveTimes += leaveInfo.Hour;
                                break;
                            default:
                                emp.TotalRestLeaveTimes += leaveInfo.Hour;
                                break;
                        }
                    }
                    excelNpoi.SetSheetData(emp.TotalFoodTimes.ToString(), rowIndex, collectIndex++);//总餐补                    
                    excelNpoi.SetSheetData(emp.WorkDayOvertimeHour.ToString(), rowIndex, collectIndex++);//平时加班
                    excelNpoi.SetSheetData(emp.RestDayOvertimeHour.ToString(), rowIndex, collectIndex++);//周末加班
                    collectIndex++;//跳过节假日加班
                    excelNpoi.SetSheetData((emp.TotalSickLeaveTimes + emp.TotalAffairsLeaveTimes).ToString(), rowIndex, collectIndex++);//病/事假
                    excelNpoi.SetSheetData((emp.TotalAnnualLeaveTimes + emp.TotalRestLeaveTimes).ToString(), rowIndex, collectIndex++);//调休/年假
                    collectIndex++;
                    excelNpoi.SetSheetData((emp.MissedPunch + emp.NoCardPunched).ToString(), rowIndex, collectIndex++);
                    excelNpoi.SetSheetData((emp.BeLateCount - 3 > 0 ? emp.BeLateCount - 3 : 0).ToString(), rowIndex, collectIndex++);//迟到次数
                    //excelNpoi.SetSheetData(emp.BeLateCount.ToString(), rowIndex, collectIndex++);//迟到次数
                    excelNpoi.SetSheetData(morning, rowIndex++, col);
                    excelNpoi.SetSheetData(afternoon, rowIndex++, col);
                    excelNpoi.SetSheetData(overtime, rowIndex++, col);
                    excelNpoi.SetSheetData(leave, rowIndex++, col);
                    excelNpoi.SetSheetData(FoodSubsidy, rowIndex++, col);
                    excelNpoi.SetSheetData(Outer, rowIndex++, col);
                }


                if (emp.ClockRule == "车间")//车间人员，平时加班时间要减调休时间，如果平时加班不够，用周末加班抵扣
                {

                    if (emp.EmployeeName == "谭东平")
                    {

                    }
                    decimal diff = emp.WorkDayOvertimeHour - Math.Abs((decimal)emp.TotalRestLeaveTimes);
                    decimal workshopRest = 0;
                    if (diff < 0)
                    {
                        workshopRest = emp.RestDayOvertimeHour + diff;
                        emp.WorkDayOvertimeHour = 0;
                        emp.RestDayOvertimeHour = workshopRest;
                    }
                    else //>=0
                    {
                        emp.WorkDayOvertimeHour = diff;
                    }
                    excelNpoi.SetSheetData(emp.WorkDayOvertimeHour.ToString(), startrow, lstDateCol + 1);//平时加班
                    if (emp.RestDayOvertimeHour >= 0)
                    {
                        excelNpoi.SetSheetData(emp.RestDayOvertimeHour.ToString(), startrow, lstDateCol + 2);//周末加班
                    }
                    else
                    {
                        excelNpoi.SetSheetData("0", startrow, lstDateCol + 2);//周末加班
                        excelNpoi.SetSheetData(emp.RestDayOvertimeHour.ToString(), startrow, lstDateCol + 4);//算事假
                    }
                }
            }

            return col;
        }

        /// <summary>
        /// 构造员工打卡数据
        /// </summary>
        /// <param name="rows1"></param>
        /// <param name="rows2"></param>
        /// <returns></returns>
        private List<Calc_EmployeeWorkAttendanceRecords> BuildEmployeeClockinData(IEnumerable<Import_WorkAttendanceRecords> rows1, IEnumerable<Import_OuterWorkAttendanceRecords> rows2, IEnumerable<Import_WorkAttendanceDetailRecords> rowsDetail)
        {
            List<Calc_EmployeeWorkAttendanceRecords> employees = new List<Calc_EmployeeWorkAttendanceRecords>();

            //计算总部打卡数据，合并账号、姓名、部门，
            foreach (var row in rows1)
            {
                //var emp1 = employees.Find(a => a.Account == row.Account&&a.EmployeeName=="冯章明");
                var emp = employees.Find(a => a.Account == row.Account);
                if (emp == null)
                {
                    emp = new Calc_EmployeeWorkAttendanceRecords();
                    emp.Account = row.Account;
                    emp.EmployeeName = row.EmployeeName;
                    emp.Depart_Text = row.Depart_Text;
                    emp.ClockRule = row.RuleText;
                    employees.Add(emp);
                }
                EmployeeAttendanceDetails d = new EmployeeAttendanceDetails();
                d.WorkDate = row.Date_Text.Split(' ')[0].ObjToDate();
                d.Account = row.Account;

                //

                string date_part = d.WorkDate.ToString("yyyy-MM-dd");
                if (row.EarliestText.Contains(":"))
                {
                    if (row.EarliestText.Contains("次日"))
                    {
                        d.EarliestTime = $"{date_part} 08:30:00".ObjToDate();
                    }
                    else
                    {
                        d.EarliestTime = $"{date_part} {row.EarliestText}:00".ObjToDate();
                    }
                }

                if (emp.EmployeeName == "周宇")
                {

                }
                if (row.LatestText.Contains(":"))
                {
                    string date_part2 = date_part;
                    string LatestText = row.LatestText;
                    if (LatestText.Contains("次日"))
                    {
                        date_part2 = d.WorkDate.AddDays(1).ToString("yyyy-MM-dd");
                        LatestText = LatestText.Replace("次日", "");
                    }
                    d.LatestTime = $"{date_part2} {LatestText}:00".ObjToDate();
                }
                //判断员工当天是否有班次
                if (row.WorkScheduling.Contains("休息"))
                    d.WorkType = 4;
                else if (row.WorkScheduling.Trim() == "--")
                    d.WorkType = 3;
                else
                {
                    d.WorkType = 1;
                }
                d.CalibrationConditionText = row.CalibrationConditionText;


                var checkInEarliestLocation = rowsDetail.FirstOrDefault(x => row.Account == x.Account && row.Date_Text == x.Date_Text
&& row.EmployeeName == x.EmployeeName && row.EarliestText == x.ReailtyText && x.Type == "上班");
                if (checkInEarliestLocation != null)
                {
                    d.CheckInEarliestLocation = checkInEarliestLocation.CheckInLocation;
                }
                else
                {
                    d.CheckInEarliestLocation = "";
                }

                var checkInLatestLocation = rowsDetail.FirstOrDefault(x => row.Account == x.Account && row.Date_Text == x.Date_Text
                        && row.EmployeeName == x.EmployeeName && row.LatestText == x.ReailtyText && x.Type == "下班");
                if(checkInLatestLocation != null)
                {
                    d.CheckInLatestLocation = checkInLatestLocation.CheckInLocation;
                }
                else
                {
                    d.CheckInLatestLocation = "";
                }


                //if (row.CalibrationConditionText.Contains("地点异常"))
                //{
                //foreach (var detail in rowsDetail)
                //{
                //    if (row.Account == detail.Account && row.Date_Text == detail.Date_Text
                //        && row.EmployeeName == detail.EmployeeName && row.EarliestText == detail.ReailtyText && detail.Type == "上班")
                //    {
                //        d.CheckInEarliestLocation = detail.CheckInLocation;
                //    }
                //    if (row.Account == detail.Account && row.Date_Text == detail.Date_Text
                //        && row.EmployeeName == detail.EmployeeName && row.EarliestText == detail.ReailtyText && detail.Type == "下班")
                //    {
                //        d.CheckInLatestLocation = detail.CheckInLocation;
                //    }
                //}
                //}
                emp.AttendanceDetails.Add(d);

            }
            //计算外部考勤表 修正员工未打卡情况
            foreach (var row in rows2)
            {
                var emp = employees.Find(a => a.Account == row.Account);
                if (emp == null)
                {
                    emp = new Calc_EmployeeWorkAttendanceRecords();
                    emp.Account = row.Account;
                    emp.EmployeeName = row.EmployeeName;
                    emp.Depart_Text = row.Depart_Text;
                    employees.Add(emp);
                }
                var WorkDate = row.Date_Text.Split(' ')[0].ObjToDate();
                var d = emp.AttendanceDetails.Find(a => a.WorkDate == WorkDate);
                if (d == null)
                {
                    //总部考勤表没有则添加
                    d = new EmployeeAttendanceDetails();
                    d.WorkDate = WorkDate;
                    d.Account = row.Account;
                    emp.AttendanceDetails.Add(d);
                }
                d.WorkType = 2; //修正为外出状态

                DateTime? startTime = null;
                DateTime? endTime = null;
                string date_part = d.WorkDate.ToString("yyyy-MM-dd");
                if (row.EarliestText.Contains(":"))
                    startTime = $"{date_part} {row.EarliestText}:00".ObjToDate();
                if (row.LatestText.Contains(":"))
                {
                    string date_part2 = date_part;
                    string LatestText = row.LatestText;
                    if (LatestText.Contains("次日"))
                    {
                        date_part2 = d.WorkDate.AddDays(1).ToString("yyyy-MM-dd");
                        LatestText = LatestText.Replace("次日", "");
                    }
                    endTime = $"{date_part2} {LatestText}:00".ObjToDate();
                }
                if (startTime == endTime)   //会出现上下班是一个时间
                {
                    if (startTime.Value.Hour <= 12)
                        endTime = null;
                    else
                        startTime = null;
                }


                if (d.EarliestTime == null && startTime != null) //上班未打卡
                {
                    d.EarliestTime = startTime;
                }//上班打开时间小于外出时间，以外出时间的上班时间为准
                else if (d.EarliestTime != null && startTime != null && startTime < d.EarliestTime)
                { d.EarliestTime = startTime; }





                if (d.LatestTime == null && endTime != null)
                { d.LatestTime = endTime; }
                else if (d.LatestTime != null && endTime != null && endTime > d.LatestTime)
                { d.LatestTime = endTime; }
                d.CheckInEarliestLocation = row.CheckInEarliestLocation;
                d.CheckInLatestLocation = row.CheckInLatestLocation;
            }

            return employees;
        }

        /// <summary>
        /// 检查打卡地点 用于计算饭补
        /// </summary>
        /// <param name="place">打卡地点</param>
        /// <returns></returns>
        private bool CheckWorkPlace(string place)
        {
            if (!place.IsNullOrEmpty())
            {
                string[] element = place.Split('|');
                switch (element.Length)
                {
                    case 0:
                        return false;
                    case 1:
                        if (element[0].Contains("上海") || element[0].Contains("打卡机"))
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    case 2:
                        if (element[0].Contains("上海") && element[1].Contains("上海"))
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    default:
                        return false;
                }
            }
            else
            {
                return false;
            }
        }

        private void btnChoose1_Click(object sender, EventArgs e)
        {
            OpenSelectFile(txtFile1);
        }


        private void OpenSelectFile(Input input)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "EXCEL|*.xlsx;";
            var result = ofd.ShowDialog();
            if (result == DialogResult.OK)
            {
                input.Text = ofd.FileName;
            }
        }

        private void btnChoose2_Click(object sender, EventArgs e)
        {
            OpenSelectFile(txtFile2);
        }

        private void btnChoose3_Click(object sender, EventArgs e)
        {
            OpenSelectFile(txtTemplateFile);
        }

        private void btnChoose4_Click(object sender, EventArgs e)
        {
            OpenCreateFile(txtProdFile);
        }

        private void OpenCreateFile(Input input)
        {

            SaveFileDialog ofd = new SaveFileDialog();
            ofd.Filter = "EXCEL|*.xlsx;";
            var result = ofd.ShowDialog();
            if (result == DialogResult.OK)
            {
                input.Text = ofd.FileName;
            }
        }
    }
}
